#include "klippy/reactor.h"
#include <gtest/gtest.h>
#include <thread>
#include <chrono>
#include <atomic>
#include <fcntl.h>
#include <unistd.h>
#include <sys/socket.h>
#include <mutex>

using namespace std::chrono_literals;

class ReactorTest : public ::testing::Test {
protected:
    void SetUp() override {
        reactor = klippy::create_reactor();
    }

    void TearDown() override {
        reactor.reset();
    }

    std::shared_ptr<klippy::Reactor> reactor;
};

// 测试基本创建和销毁
TEST_F(ReactorTest, CreateDestroy) {
    ASSERT_NE(reactor, nullptr);
}

// 测试定时器功能
TEST_F(ReactorTest, TimerBasic) {
    std::atomic<int> counter{0};
    
    // 注册一个100ms的定时器
    reactor->register_timer([&counter]() {
        counter++;
    }, 100ms);
    
    // 在另一个线程中运行reactor
    std::thread reactor_thread([this]() {
        reactor->run();
    });
    
    // 等待足够的时间让定时器触发几次
    std::this_thread::sleep_for(550ms);
    
    // 停止reactor
    reactor->stop();
    reactor_thread.join();
    
    // 验证定时器被触发了约5次（允许有一定误差）
    EXPECT_GE(counter, 4);
    EXPECT_LE(counter, 6);
}

// 测试定时器更新
TEST_F(ReactorTest, TimerUpdate) {
    std::atomic<int> counter{0};
    std::atomic<bool> updated{false};
    
    // 注册一个500ms的定时器
    reactor->register_timer([&]() {
        counter++;
        if (counter == 1 && !updated) {
            // 第一次触发后，更新为100ms
            reactor->update_timer(100ms);
            updated = true;
        }
    }, 500ms);
    
    // 在另一个线程中运行reactor
    std::thread reactor_thread([this]() {
        reactor->run();
    });
    
    // 等待足够的时间
    std::this_thread::sleep_for(1000ms);
    
    // 停止reactor
    reactor->stop();
    reactor_thread.join();
    
    // 验证定时器在更新后触发更频繁
    EXPECT_GT(counter, 3);
}

// 测试文件描述符事件
TEST_F(ReactorTest, FileDescriptorEvent) {
    int fds[2];
    ASSERT_EQ(pipe(fds), 0);
    
    std::atomic<bool> callback_called{false};
    
    // 注册文件描述符回调
    reactor->register_fd(fds[0], [&](int fd) {
        char buffer[10];
        read(fd, buffer, sizeof(buffer));
        callback_called = true;
    });
    
    // 在另一个线程中运行reactor
    std::thread reactor_thread([this]() {
        reactor->run();
    });
    
    // 写入数据触发事件
    write(fds[1], "test", 4);
    
    // 等待回调执行
    std::this_thread::sleep_for(100ms);
    
    // 停止reactor
    reactor->stop();
    reactor_thread.join();
    
    // 清理
    close(fds[0]);
    close(fds[1]);
    
    // 验证回调被调用
    EXPECT_TRUE(callback_called);
}

// 测试异步回调
TEST_F(ReactorTest, AsyncCallback) {
    std::atomic<bool> callback_called{false};
    
    // 在另一个线程中运行reactor
    std::thread reactor_thread([this]() {
        reactor->run();
    });
    
    // 注册异步回调
    reactor->register_async_callback([&]() {
        callback_called = true;
    });
    
    // 等待回调执行
    std::this_thread::sleep_for(100ms);
    
    // 停止reactor
    reactor->stop();
    reactor_thread.join();
    
    // 验证回调被调用
    EXPECT_TRUE(callback_called);
}

// 测试多个异步回调的顺序
TEST_F(ReactorTest, MultipleAsyncCallbacks) {
    std::vector<int> execution_order;
    std::mutex mutex;
    
    // 在另一个线程中运行reactor
    std::thread reactor_thread([this]() {
        reactor->run();
    });
    
    // 注册多个异步回调
    for (int i = 0; i < 5; i++) {
        reactor->register_async_callback([i, &execution_order, &mutex]() {
            std::lock_guard<std::mutex> lock(mutex);
            execution_order.push_back(i);
        });
    }
    
    // 等待回调执行
    std::this_thread::sleep_for(100ms);
    
    // 停止reactor
    reactor->stop();
    reactor_thread.join();
    
    // 验证所有回调都被调用，且顺序正确
    EXPECT_EQ(execution_order.size(), 5);
    for (int i = 0; i < 5; i++) {
        EXPECT_EQ(execution_order[i], i);
    }
}

// 测试互斥锁
TEST_F(ReactorTest, Mutex) {
    std::atomic<int> counter{0};
    std::atomic<bool> mutex_acquired{false};
    
    // 在另一个线程中运行reactor
    std::thread reactor_thread([this]() {
        reactor->run();
    });
    
    // 在主线程中获取互斥锁
    reactor->acquire_mutex();
    mutex_acquired = true;
    
    // 注册一个异步回调，它会尝试增加计数器
    reactor->register_async_callback([&]() {
        counter++;
    });
    
    // 等待一段时间，回调应该被阻塞
    std::this_thread::sleep_for(100ms);
    
    // 验证回调没有执行（因为互斥锁被主线程持有）
    EXPECT_EQ(counter, 0);
    
    // 释放互斥锁
    reactor->release_mutex();
    
    // 等待回调执行
    std::this_thread::sleep_for(100ms);
    
    // 停止reactor
    reactor->stop();
    reactor_thread.join();
    
    // 验证回调被执行
    EXPECT_EQ(counter, 1);
    EXPECT_TRUE(mutex_acquired);
}

// 测试错误处理（无效的文件描述符）
TEST_F(ReactorTest, InvalidFileDescriptor) {
    // 尝试注册一个无效的文件描述符
    EXPECT_THROW(reactor->register_fd(-1, [](int) {}), std::system_error);
}